home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / pixtest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  32.7 KB  |  1,299 lines

  1. /*
  2. ** Copyright 1994, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. */
  18. #include <GL/glx.h>
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include <string.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <fcntl.h>
  25. #include <unistd.h>
  26. #include <stdlib.h>
  27. #include <X11/keysym.h>
  28. #include <malloc.h>
  29.  
  30. static int RGB_SB_attributes[] = {
  31.     GLX_RGBA,
  32.     GLX_RED_SIZE, 1,
  33.     GLX_GREEN_SIZE, 1,
  34.     GLX_BLUE_SIZE, 1,
  35.     GLX_DEPTH_SIZE, 1,
  36.     GLX_STENCIL_SIZE, 1,
  37.     None,
  38. };
  39.  
  40. static int RGB_DB_attributes[] = {
  41.     GLX_RGBA,
  42.     GLX_RED_SIZE, 1,
  43.     GLX_GREEN_SIZE, 1,
  44.     GLX_BLUE_SIZE, 1,
  45.     GLX_DOUBLEBUFFER,
  46.     GLX_DEPTH_SIZE, 1,
  47.     GLX_STENCIL_SIZE, 1,
  48.     None,
  49. };
  50.  
  51. static int CI_SB_attributes[] = {
  52.     GLX_DEPTH_SIZE, 1,
  53.     GLX_STENCIL_SIZE, 1,
  54.     None,
  55. };
  56.  
  57. static int CI_DB_attributes[] = {
  58.     GLX_DOUBLEBUFFER,
  59.     GLX_DEPTH_SIZE, 1,
  60.     GLX_STENCIL_SIZE, 1,
  61.     None,
  62. };
  63.  
  64. Display *dpy;
  65. Window window;
  66. GLfloat *fltImage;      /* GL_RGBA, GL_FLOAT */
  67. GLubyte *bitmapImage;
  68. GLint imageWidth, imageHeight;
  69. GLfloat zoomx, zoomy;
  70. void *newimage;
  71. GLenum type, format, copyFormat;
  72. GLint centerx, centery;
  73. GLint scissor;
  74. GLint biasing;
  75. GLint mapping;
  76. GLint test;
  77. GLint rgbMode;
  78. GLint alphatst;
  79. GLint swapBytes;
  80. GLfloat quant4[4];
  81. void *tempbuf;
  82. GLint windowWidth, windowHeight;
  83. GLint alignShift;
  84. GLboolean dlisted;
  85. GLboolean doubleBuffer;
  86. GLuint dlistnum;
  87. GLuint maxindex;
  88.  
  89. #define TEST_DRAW       0
  90. #define TEST_READ       1
  91. #define TEST_COPY       2
  92.  
  93. typedef struct _rawImageRec {
  94.     unsigned short imagic;
  95.     unsigned short type;
  96.     unsigned short dim;
  97.     unsigned short sizeX, sizeY, sizeZ;
  98.     unsigned long min, max;
  99.     unsigned long wasteBytes;
  100.     char name[80];
  101.     unsigned long colorMap;
  102.     FILE *file;
  103.     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  104.     unsigned long rleEnd;
  105.     unsigned long *rowStart;
  106.     long *rowSize;
  107. } rawImageRec;
  108.  
  109. typedef struct image {
  110.     long sizeX, sizeY;
  111.     unsigned char *data;
  112. } Image;
  113.  
  114. Image *image;
  115.  
  116. static rawImageRec *RawImageOpen(char *fileName)
  117. {
  118.     rawImageRec *raw;
  119.     long x;
  120.  
  121.     raw = (rawImageRec *)malloc(sizeof(rawImageRec));
  122.     if (raw == NULL) {
  123.         fprintf(stderr, "Out of memory!\n");
  124.         exit(1);
  125.     }
  126.     if ((raw->file = fopen(fileName, "rb")) == NULL) {
  127.         perror(fileName);
  128.         exit(1);
  129.     }
  130.  
  131.     fread(raw, 1, 12, raw->file );
  132.  
  133.     raw->tmp = (unsigned char *)malloc(raw->sizeX*256);
  134.     raw->tmpR = (unsigned char *)malloc(raw->sizeX*256);
  135.     raw->tmpG = (unsigned char *)malloc(raw->sizeX*256);
  136.     raw->tmpB = (unsigned char *)malloc(raw->sizeX*256);
  137.     if (raw->tmp == NULL || raw->tmpR == NULL || raw->tmpG == NULL ||
  138.             raw->tmpB == NULL) {
  139.         fprintf(stderr, "Out of memory!\n");
  140.         exit(1);
  141.     }
  142.     if ((raw->type & 0xFF00) == 0x0100) {
  143.         x = raw->sizeY * raw->sizeZ * sizeof(long);
  144.         raw->rowStart = (unsigned long *)malloc(x);
  145.         raw->rowSize = (long *)malloc(x);
  146.         if (raw->rowStart == NULL || raw->rowSize == NULL) {
  147.             fprintf(stderr, "Out of memory!\n");
  148.             exit(1);
  149.         }
  150.         raw->rleEnd = 512 + (2 * x);
  151.  
  152.         fseek(raw->file, 512L, SEEK_SET);
  153.         fread(raw->rowStart, 1, x, raw->file);
  154.         fread(raw->rowSize, 1, x, raw->file);
  155.     }
  156.     return raw;
  157. }
  158.  
  159. static void RawImageClose(rawImageRec *raw)
  160. {
  161.     fclose(raw->file);
  162.     free(raw->tmp);
  163.     free(raw->tmpR);
  164.     free(raw->tmpG);
  165.     free(raw->tmpB);
  166.     free(raw);
  167. }
  168.  
  169. static void RawImageGetRow(rawImageRec *raw, unsigned char *buf, long y, long z)
  170. {
  171.     unsigned char *iPtr, *oPtr, pixel;
  172.     long count;
  173.  
  174.     if ((raw->type & 0xFF00) == 0x0100) {
  175.         fseek(raw->file, raw->rowStart[y+z*raw->sizeY], SEEK_SET);
  176.         fread(raw->tmp, 1, raw->rowSize[y+z*raw->sizeY], raw->file);
  177.  
  178.         iPtr = raw->tmp;
  179.         oPtr = buf;
  180.         while (1) {
  181.             pixel = *iPtr++;
  182.             count = (long)(pixel & 0x7f);
  183.             if (!count)
  184.                 return;
  185.             if (pixel & 0x80) {
  186.                 while (count--) {
  187.                     *oPtr++ = *iPtr++;
  188.                 }
  189.             } else {
  190.                 pixel = *iPtr++;
  191.                 while (count--) {
  192.                     *oPtr++ = pixel;
  193.                 }
  194.             }
  195.         }
  196.     } else {
  197.         fseek(raw->file, 512L+(y*raw->sizeX)+(z*raw->sizeX*raw->sizeY),
  198.                 SEEK_SET);
  199.         fread(buf, 1, raw->sizeX, raw->file);
  200.     }
  201. }
  202.  
  203. static void RawImageGetData(rawImageRec *raw, Image *final)
  204. {
  205.     long i, j;
  206.     unsigned char *ptr;
  207.  
  208.     final->data = (unsigned char *)malloc((raw->sizeX+1)*(raw->sizeY+1)*4);
  209.     if (final->data == NULL) {
  210.         fprintf(stderr, "Out of memory!\n");
  211.         exit(1);
  212.     }
  213.  
  214.     ptr = final->data;
  215.     for (i=0; i<raw->sizeY; i++) {
  216.         RawImageGetRow(raw, raw->tmpR, i, 0);
  217.         RawImageGetRow(raw, raw->tmpG, i, 1);
  218.         RawImageGetRow(raw, raw->tmpB, i, 2);
  219.         for (j=0; j<raw->sizeX; j++) {
  220.             *ptr++ = *(raw->tmpR + j);
  221.             *ptr++ = *(raw->tmpG + j);
  222.             *ptr++ = *(raw->tmpB + j);
  223.         }
  224.     }
  225. }
  226.  
  227. Image *ImageLoad(char *fileName)
  228. {
  229.     rawImageRec *raw;
  230.     Image *final;
  231.  
  232.     raw = RawImageOpen(fileName);
  233.     final = (Image *)malloc(sizeof(Image));
  234.     if (final == NULL) {
  235.         fprintf(stderr, "Out of memory!\n");
  236.         exit(1);
  237.     }
  238.     final->sizeX = raw->sizeX;
  239.     final->sizeY = raw->sizeY;
  240.     RawImageGetData(raw, final);
  241.     RawImageClose(raw);
  242.     return final;
  243. }
  244.  
  245. void createFloatImage(void)
  246. {
  247.     GLubyte *rawData;
  248.     GLint x,y;
  249.     GLfloat *finalImage;
  250.     GLfloat alpha;
  251.  
  252.     rawData = image->data;
  253.     fltImage = malloc(imageWidth * imageHeight * sizeof(GLfloat) * 4);
  254.     tempbuf = malloc(imageWidth * imageHeight * sizeof(GLdouble) * 4 + 3);
  255.     finalImage = fltImage;
  256.     for (y = 0; y < imageHeight; y++) {
  257.         for (x = 0; x < imageWidth; x++) {
  258.             *finalImage++ = *rawData++ / 255.0;
  259.             alpha = *finalImage++ = *rawData++ / 255.0;
  260.             *finalImage++ = *rawData++ / 255.0;
  261.             *finalImage++ = alpha;
  262.         }
  263.     }
  264. }
  265.  
  266. static void Init(void)
  267. {
  268.     int i;
  269.     GLfloat array[8];
  270.  
  271.     imageWidth = image->sizeX;
  272.     imageHeight = image->sizeY;
  273.     centerx = image->sizeX;
  274.     centery = image->sizeY;
  275.  
  276.     createFloatImage();
  277.     newimage = image->data;
  278.  
  279.     for (i=0; i<4; i++) {
  280.         quant4[i] = (2*i+1)/8.0;
  281.     }
  282.  
  283.     glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 4, quant4);
  284.     glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 4, quant4);
  285.     glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 4, quant4);
  286.     glPixelMapfv(GL_PIXEL_MAP_A_TO_A, 4, quant4);
  287.     for (i=0; i<8; i++) {
  288.         array[i] = (i&1) ? 1 : 0;
  289.     }
  290.     glPixelMapfv(GL_PIXEL_MAP_I_TO_R, 8, array);
  291.     for (i=0; i<8; i++) {
  292.         array[i] = (i&2) ? 1 : 0;
  293.     }
  294.     glPixelMapfv(GL_PIXEL_MAP_I_TO_G, 8, array);
  295.     for (i=0; i<8; i++) {
  296.         array[i] = (i&4) ? 1 : 0;
  297.     }
  298.     glPixelMapfv(GL_PIXEL_MAP_I_TO_B, 8, array);
  299.     array[0] = 0;
  300.     array[1] = 1;
  301.     glPixelMapfv(GL_PIXEL_MAP_I_TO_A, 2, array);
  302.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  303.     glPixelStorei(GL_PACK_ALIGNMENT, 1);
  304.     glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  305.     glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
  306.     glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
  307.     glPixelStorei(GL_PACK_LSB_FIRST, GL_TRUE);
  308.     glScissor(0,0,windowWidth,windowHeight);
  309.     glEnable(GL_SCISSOR_TEST);
  310.     glColor3f(1.0, 1.0, 1.0);
  311.  
  312.     dlistnum = glGenLists(1);
  313. }
  314.  
  315. static void Redraw(void)
  316. {
  317.     GLubyte *s;
  318.     int i,j;
  319.     static int lasttest = TEST_DRAW;
  320.  
  321.     glViewport(0, 0, 4*imageWidth, 2*imageHeight);
  322.     glMatrixMode(GL_PROJECTION);
  323.     glLoadIdentity();
  324.     glOrtho(0, 4*imageWidth, 0, 2*imageHeight, -1, 1);
  325.     glMatrixMode(GL_MODELVIEW);
  326.     glScissor(0,0,windowWidth,windowHeight);
  327.  
  328.     glClearColor(0.0, 0.0, 0.0, 0.0);
  329.  
  330.     if (alphatst && (type == GL_BITMAP ||
  331.             format == GL_ALPHA || format == GL_LUMINANCE_ALPHA)) {
  332.         glClearColor(0.3, 0.3, 0.3, 0.0);
  333.     }
  334.  
  335.     glClear(GL_COLOR_BUFFER_BIT);
  336.  
  337.     if (test != lasttest) {
  338.         lasttest = test;
  339.         switch(test) {
  340.           case TEST_DRAW:
  341.             printf("Test = DrawPixels\n");
  342.             break;
  343.           case TEST_COPY:
  344.             printf("Test = CopyPixels\n");
  345.             break;
  346.           case TEST_READ:
  347.             printf("Test = ReadPixels\n");
  348.             break;
  349.         }
  350.     }
  351.  
  352.     if (format == GL_DEPTH_COMPONENT) {
  353.         glDepthFunc(GL_ALWAYS);
  354.         glClearDepth(0.5);
  355.         glClear(GL_DEPTH_BUFFER_BIT);
  356.         glEnable(GL_DEPTH_TEST);
  357.     }
  358.     if (format == GL_STENCIL_INDEX) {
  359.         glEnable(GL_STENCIL_TEST);
  360.         glClearStencil(0);
  361.         glClear(GL_STENCIL_BUFFER_BIT);
  362.         glStencilFunc(GL_ALWAYS, 1, 255);
  363.     }
  364.  
  365.     glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
  366.  
  367.     if (test == TEST_READ || test == TEST_COPY) {
  368.         glRasterPos3f(0,0,-1);
  369.         glBitmap(0,0,0,0,centerx - imageWidth/2.0,
  370.             centery - imageHeight/2.0,NULL);
  371.         glDrawPixels(imageWidth, imageHeight, format, type,
  372.             newimage);
  373.     }
  374.  
  375.     glPixelZoom(zoomx, zoomy);
  376.  
  377.     if (format == GL_DEPTH_COMPONENT) {
  378.         glDepthFunc(GL_GEQUAL);
  379.     }
  380.     if (biasing) {
  381.         glPixelTransferf(GL_RED_SCALE, -1);
  382.         glPixelTransferf(GL_RED_BIAS, 1);
  383.         glPixelTransferf(GL_GREEN_SCALE, -1);
  384.         glPixelTransferf(GL_GREEN_BIAS, 1);
  385.         glPixelTransferf(GL_BLUE_SCALE, -1);
  386.         glPixelTransferf(GL_BLUE_BIAS, 1);
  387.     }
  388.     if (mapping) {
  389.         glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
  390.     }
  391.     if (scissor) {
  392.         glScissor(imageWidth/2, imageHeight/2,
  393.                 imageWidth, imageHeight);
  394.     }
  395.     if (alphatst) {
  396.         glEnable(GL_ALPHA_TEST);
  397.         glAlphaFunc(GL_GREATER, 0.5);
  398.     }
  399.  
  400.     if (test == TEST_DRAW) {
  401.     if (dlisted) {
  402.         glNewList(dlistnum, GL_COMPILE);
  403.     }
  404.         glRasterPos3f(0,0,-1);
  405.         glBitmap(0,0,0,0,centerx - zoomx * imageWidth / 2,
  406.             centery - zoomy * imageHeight / 2,NULL);
  407.         glDrawPixels(imageWidth, imageHeight, format, type,
  408.             newimage);
  409.     if (dlisted) {
  410.         glEndList();
  411.         glCallList(dlistnum);
  412.     }
  413.     } else if (test == TEST_READ) {
  414.         glReadPixels(centerx - (1+imageWidth)/2,
  415.             centery - (1+imageHeight)/2, imageWidth,
  416.             imageHeight, format, type, ((GLubyte *) tempbuf) + alignShift);
  417.     } else if (test == TEST_COPY) {
  418.         glRasterPos3f(0,0,-1);
  419.         glBitmap(0,0,0,0,imageWidth - zoomx * imageWidth / 2,
  420.             imageHeight - zoomy * imageHeight / 2,NULL);
  421.         glCopyPixels(centerx - (1+imageWidth) / 2,
  422.             centery - (1+imageHeight) / 2, imageWidth,
  423.             imageHeight, copyFormat);
  424.     }
  425.  
  426.     if (biasing) {
  427.         glPixelTransferf(GL_RED_SCALE, 1);
  428.         glPixelTransferf(GL_RED_BIAS, 0);
  429.         glPixelTransferf(GL_GREEN_SCALE, 1);
  430.         glPixelTransferf(GL_GREEN_BIAS, 0);
  431.         glPixelTransferf(GL_BLUE_SCALE, 1);
  432.         glPixelTransferf(GL_BLUE_BIAS, 0);
  433.     }
  434.     if (mapping) {
  435.         glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
  436.     }
  437.  
  438.     if (test == TEST_READ) {
  439.         glRasterPos3f(0,0,-1);
  440.         glBitmap(0,0,0,0,imageWidth - zoomx * imageWidth / 2,
  441.             imageHeight - zoomy * imageHeight / 2,NULL);
  442.         glDrawPixels(imageWidth, imageHeight, format, type,
  443.             ((GLubyte *) tempbuf) + alignShift);
  444.     }
  445.     if (format == GL_STENCIL_INDEX) {
  446.         if (type == GL_BITMAP) {
  447.             glStencilFunc(GL_EQUAL, 1, 1);
  448.         } else if (type == GL_BYTE) {
  449.         glStencilFunc(GL_LEQUAL, (maxindex/4)+1, maxindex);
  450.     } else {
  451.             glStencilFunc(GL_LEQUAL, (maxindex/2)+1, maxindex);
  452.         }
  453.         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  454.         glRecti(0, 0, 4*imageWidth, 2*imageHeight);
  455.     }
  456.     glFlush();
  457.  
  458.     if (format == GL_DEPTH_COMPONENT) {
  459.         glDisable(GL_DEPTH_TEST);
  460.     }
  461.     if (format == GL_STENCIL_INDEX) {
  462.         glDisable(GL_STENCIL_TEST);
  463.     }
  464.     if (scissor) {
  465.         glScissor(0,0,windowWidth,windowHeight);
  466.     }
  467.     if (alphatst) {
  468.         glDisable(GL_ALPHA_TEST);
  469.     }
  470.  
  471.     glPixelZoom(1.0, 1.0);
  472.  
  473.     if (doubleBuffer) {
  474.     glXSwapBuffers(dpy, window);
  475.     }
  476. }
  477.  
  478. GLboolean okCombo(void)
  479. {
  480.     if (rgbMode && type == GL_BITMAP && format != GL_COLOR_INDEX &&
  481.             format != GL_STENCIL_INDEX) {
  482.         return GL_FALSE;
  483.     }
  484.     if (test == TEST_READ && rgbMode && format == GL_COLOR_INDEX) {
  485.         return GL_FALSE;
  486.     }
  487.     return GL_TRUE;
  488. }
  489.  
  490. void makeNewImage(void)
  491. {
  492.     int components;
  493.     int bytesPerComp;
  494.     GLfloat *myimage;
  495.     int i,j,k;
  496.     int index;
  497.     GLfloat indexscale;
  498.     int imageSize;
  499.  
  500.     if (swapBytes) {
  501.         if (type == GL_BITMAP) {
  502.             printf("MSB_FIRST, ");
  503.         } else {
  504.             printf("SWAP_BYTES, ");
  505.         }
  506.     } else {
  507.         if (type == GL_BITMAP) {
  508.             printf("LSB_FIRST, ");
  509.         }
  510.     }
  511.     if (alignShift) {
  512.         printf("(%d*), ", alignShift);
  513.     }
  514.     switch(type) {
  515.       case GL_BYTE:
  516.         bytesPerComp = 1;
  517.         printf("Type: GL_BYTE, ");
  518.         break;
  519.       case GL_UNSIGNED_BYTE:
  520.         bytesPerComp = 1;
  521.         printf("Type: GL_UNSIGNED_BYTE, ");
  522.         break;
  523.       case GL_INT:
  524.         bytesPerComp = 4;
  525.         printf("Type: GL_INT, ");
  526.         break;
  527.       case GL_UNSIGNED_INT:
  528.         bytesPerComp = 4;
  529.         printf("Type: GL_UNSIGNED_INT, ");
  530.         break;
  531.       case GL_BITMAP:
  532.         printf("Type: GL_BITMAP, ");
  533.         break;
  534.       case GL_FLOAT:
  535.         bytesPerComp = 4;
  536.         printf("Type: GL_FLOAT, ");
  537.         break;
  538.       case GL_UNSIGNED_SHORT:
  539.         bytesPerComp = 2;
  540.         printf("Type: GL_UNSIGNED_SHORT, ");
  541.         break;
  542.       case GL_SHORT:
  543.         bytesPerComp = 2;
  544.         printf("Type: GL_SHORT, ");
  545.         break;
  546.     }
  547.     copyFormat = GL_COLOR;
  548.     index = 0;
  549.     switch(format) {
  550.       case GL_RGB:
  551.         components = 3;
  552.         printf("Format: GL_RGB\n");
  553.         break;
  554.       case GL_RED:
  555.         components = 1;
  556.         printf("Format: GL_RED\n");
  557.         break;
  558.       case GL_GREEN:
  559.         components = 1;
  560.         printf("Format: GL_GREEN\n");
  561.         break;
  562.       case GL_BLUE:
  563.         components = 1;
  564.         printf("Format: GL_BLUE\n");
  565.         break;
  566.       case GL_ALPHA:
  567.         components = 1;
  568.         printf("Format: GL_ALPHA\n");
  569.         break;
  570.       case GL_LUMINANCE_ALPHA:
  571.         components = 2;
  572.         printf("Format: GL_LUMINANCE_ALPHA\n");
  573.         break;
  574.       case GL_LUMINANCE:
  575.         components = 1;
  576.         printf("Format: GL_LUMINANCE\n");
  577.         break;
  578.       case GL_RGBA:
  579.         components = 4;
  580.         printf("Format: GL_RGBA\n");
  581.         break;
  582.       case GL_COLOR_INDEX:
  583.         components = 1;
  584.         index = 1;
  585.         printf("Format: GL_COLOR_INDEX\n");
  586.         break;
  587.       case GL_DEPTH_COMPONENT:
  588.         components = 1;
  589.         copyFormat = GL_DEPTH;
  590.         printf("Format: GL_DEPTH_COMPONENT\n");
  591.         break;
  592.       case GL_STENCIL_INDEX:
  593.         components = 1;
  594.         index = 1;
  595.         copyFormat = GL_STENCIL;
  596.         printf("Format: GL_STENCIL_INDEX\n");
  597.         break;
  598.     }
  599.     if (index) {
  600.     GLint bufferbits, typebits;
  601.     switch (format) {
  602.       case GL_COLOR_INDEX:
  603.         glGetIntegerv(GL_INDEX_BITS, &bufferbits);
  604.         break;
  605.       case GL_STENCIL_INDEX:
  606.         glGetIntegerv(GL_STENCIL_BITS, &bufferbits);
  607.         break;
  608.     }
  609.     maxindex = (bufferbits > 0) ? ~(~1 << bufferbits-1) : 0;
  610.     switch (type) {
  611.        case GL_BITMAP:
  612.        case GL_FLOAT:
  613.          typebits = bufferbits;
  614.          break;
  615.        case GL_BYTE:
  616.          typebits = 8*sizeof(GLbyte) - 1;
  617.          break;
  618.        case GL_UNSIGNED_BYTE:
  619.          typebits = 8*sizeof(GLubyte);
  620.          break;
  621.        case GL_INT:
  622.          typebits = 8*sizeof(GLint) - 1;
  623.          break;
  624.        case GL_UNSIGNED_INT:
  625.          typebits = 8*sizeof(GLuint);
  626.          break;
  627.        case GL_SHORT:
  628.          typebits = 8*sizeof(GLshort) - 1;
  629.          break;
  630.        case GL_UNSIGNED_SHORT:
  631.          typebits = 8*sizeof(GLushort);
  632.          break;
  633.     }
  634.     if (typebits < bufferbits) {
  635.         indexscale = (GLfloat) pow(2.0, (double) typebits) - 1.0;
  636.     } else {
  637.         indexscale = (GLfloat) pow(2.0, (double) bufferbits) - 1.0;
  638.     }
  639.     } else {
  640.     maxindex = 0;
  641.     indexscale = 0;
  642.     }
  643.  
  644.     /* Build the new image */
  645.     free((void *) ((int) (newimage) & 0xfffffffc));
  646.  
  647.     if (type != GL_BITMAP) {
  648.         imageSize = imageWidth*imageHeight*components*bytesPerComp;
  649.     } else {
  650.         imageSize = ((imageWidth + 7)/8)*imageHeight;
  651.     }
  652.     newimage = malloc(imageSize + 3);
  653.  
  654.     myimage = fltImage;
  655.     if (format == GL_GREEN) myimage += 1;
  656.     else if (format == GL_BLUE || format == GL_LUMINANCE ||
  657.             format == GL_LUMINANCE_ALPHA) myimage += 2;
  658.     else if (format == GL_ALPHA) myimage += 3;
  659.     if (type == GL_BITMAP) {
  660.         GLubyte *data;
  661.         GLint bit;
  662.         GLubyte byte;
  663.  
  664.         data = newimage;
  665.         for (i=0; i<imageHeight; i++) {
  666.             bit = 0;
  667.             byte = 0;
  668.             for (j=0; j<imageWidth; j++) {
  669.                 if (*myimage++ > 0.5) {
  670.                     if (swapBytes) {
  671.                         byte |= 1<<(7-bit);
  672.                     } else {
  673.                         byte |= 1<<bit;
  674.                     }
  675.                 }
  676.                 bit++;
  677.                 if (bit == 8) {
  678.                     bit = 0;
  679.                     *data++ = byte;
  680.                     byte = 0;
  681.                 }
  682.                 myimage += 3;
  683.             }
  684.             if (bit) {
  685.                 *data++ = byte;
  686.             }
  687.         }
  688.     } else if (type == GL_UNSIGNED_BYTE) {
  689.         GLubyte *data;
  690.  
  691.         data = newimage;
  692.         for (i=0; i<imageHeight; i++) {
  693.             for (j=0; j<imageWidth; j++) {
  694.                 for (k=0; k<components; k++) {
  695.             if (index) {
  696.             *data++ = *myimage++ * indexscale;
  697.             } else {
  698.             *data++ = *myimage++ * 255.0;
  699.             }
  700.                 }
  701.                 myimage+=(4-components);
  702.             }
  703.         }
  704.     } else if (type == GL_BYTE) {
  705.         GLbyte *data;
  706.  
  707.         data = newimage;
  708.         for (i=0; i<imageHeight; i++) {
  709.             for (j=0; j<imageWidth; j++) {
  710.                 for (k=0; k<components; k++) {
  711.                     if (index) {
  712.                         *data++ = *myimage++ * indexscale;
  713.                     } else {
  714.                         *data++ = *myimage++ * 127.0;
  715.                     }
  716.                 }
  717.                 myimage+=(4-components);
  718.             }
  719.         }
  720.     } else if (type == GL_UNSIGNED_SHORT) {
  721.         GLushort *data;
  722.         GLubyte *temp1, *temp2;
  723.         GLushort answer;
  724.  
  725.         data = newimage;
  726.         for (i=0; i<imageHeight; i++) {
  727.             for (j=0; j<imageWidth; j++) {
  728.                 for (k=0; k<components; k++) {
  729.                     if (index) {
  730.                         answer = *myimage++ * indexscale;
  731.                     } else {
  732.                         answer = *myimage++ * (GLfloat) 65535.0;
  733.                     }
  734.                     if (swapBytes) {
  735.                         temp2 = (GLubyte *) &answer;
  736.                         temp1 = (GLubyte *) data;
  737.                         temp1[0] = temp2[1];
  738.                         temp1[1] = temp2[0];
  739.                     } else {
  740.                         data[0] = answer;
  741.                     }
  742.                     data++;
  743.                 }
  744.                 myimage+=(4-components);
  745.             }
  746.         }
  747.     } else if (type == GL_SHORT) {
  748.         GLshort *data;
  749.         GLubyte *temp1, *temp2;
  750.         GLshort answer;
  751.  
  752.         data = newimage;
  753.         for (i=0; i<imageHeight; i++) {
  754.             for (j=0; j<imageWidth; j++) {
  755.                 for (k=0; k<components; k++) {
  756.                     if (index) {
  757.                         answer = *myimage++ * indexscale;
  758.                     } else {
  759.                         answer = *myimage++ * (GLfloat) 32767.0;
  760.                     }
  761.                     if (swapBytes) {
  762.                         temp2 = (GLubyte *) &answer;
  763.                         temp1 = (GLubyte *) data;
  764.                         temp1[0] = temp2[1];
  765.                         temp1[1] = temp2[0];
  766.                     } else {
  767.                         data[0] = answer;
  768.                     }
  769.                     data++;
  770.                 }
  771.                 myimage+=(4-components);
  772.             }
  773.         }
  774.     } else if (type == GL_INT) {
  775.         GLint *data;
  776.         GLubyte *temp1, *temp2;
  777.         GLint answer;
  778.  
  779.         data = newimage;
  780.         for (i=0; i<imageHeight; i++) {
  781.             for (j=0; j<imageWidth; j++) {
  782.                 for (k=0; k<components; k++) {
  783.                     if (index) {
  784.                         answer = *myimage++ * indexscale;
  785.                     } else {
  786.                         answer = *myimage++ * (GLfloat) 2147482500.0;
  787.                     }
  788.                     if (swapBytes) {
  789.                         temp2 = (GLubyte *) &answer;
  790.                         temp1 = (GLubyte *) data;
  791.                         temp1[0] = temp2[3];
  792.                         temp1[1] = temp2[2];
  793.                         temp1[2] = temp2[1];
  794.                         temp1[3] = temp2[0];
  795.                     } else {
  796.                         data[0] = answer;
  797.                     }
  798.                     data++;
  799.                 }
  800.                 myimage+=(4-components);
  801.             }
  802.         }
  803.     } else if (type == GL_UNSIGNED_INT) {
  804.         GLuint *data;
  805.         GLubyte *temp1, *temp2;
  806.         GLuint answer;
  807.  
  808.         data = newimage;
  809.         for (i=0; i<imageHeight; i++) {
  810.             for (j=0; j<imageWidth; j++) {
  811.                 for (k=0; k<components; k++) {
  812.                     if (index) {
  813.                         answer = *myimage++ * indexscale;
  814.                     } else {
  815.                         answer = *myimage++ * (GLfloat) 4294965000.0;
  816.                     }
  817.                     if (swapBytes) {
  818.                         temp2 = (GLubyte *) &answer;
  819.                         temp1 = (GLubyte *) data;
  820.                         temp1[0] = temp2[3];
  821.                         temp1[1] = temp2[2];
  822.                         temp1[2] = temp2[1];
  823.                         temp1[3] = temp2[0];
  824.                     } else {
  825.                         data[0] = answer;
  826.                     }
  827.                     data++;
  828.                 }
  829.                 myimage+=(4-components);
  830.             }
  831.         }
  832.     } else if (type == GL_FLOAT) {
  833.         GLfloat *data;
  834.         GLubyte *temp1, *temp2;
  835.         GLfloat answer;
  836.  
  837.         data = newimage;
  838.         for (i=0; i<imageHeight; i++) {
  839.             for (j=0; j<imageWidth; j++) {
  840.                 for (k=0; k<components; k++) {
  841.                     if (index) {
  842.                         answer = *myimage++ * indexscale;
  843.                     } else {
  844.                         answer = *myimage++;
  845.                     }
  846.                     if (swapBytes) {
  847.                         temp2 = (GLubyte *) &answer;
  848.                         temp1 = (GLubyte *) data;
  849.                         temp1[0] = temp2[3];
  850.                         temp1[1] = temp2[2];
  851.                         temp1[2] = temp2[1];
  852.                         temp1[3] = temp2[0];
  853.                     } else {
  854.                         data[0] = answer;
  855.                     }
  856.                     data++;
  857.                 }
  858.                 myimage+=(4-components);
  859.             }
  860.         }
  861.     }
  862.     if (alignShift) {
  863.         memcpy((void *) (((int) newimage)+alignShift), newimage, imageSize);
  864.         newimage = (void *) (((int) newimage)+alignShift);
  865.     }
  866. }
  867.  
  868. void changeType(void)
  869. {
  870.     do {
  871.         switch(type) {
  872.           case GL_UNSIGNED_BYTE:
  873.             type = GL_BYTE;
  874.             break;
  875.           case GL_BYTE:
  876.             type = GL_UNSIGNED_SHORT;
  877.             break;
  878.           case GL_UNSIGNED_SHORT:
  879.             type = GL_SHORT;
  880.             break;
  881.           case GL_SHORT:
  882.             type = GL_UNSIGNED_INT;
  883.             break;
  884.           case GL_UNSIGNED_INT:
  885.             type = GL_INT;
  886.             break;
  887.           case GL_INT:
  888.             type = GL_FLOAT;
  889.             break;
  890.           case GL_FLOAT:
  891.             type = GL_BITMAP;
  892.             break;
  893.           case GL_BITMAP:
  894.             type = GL_UNSIGNED_BYTE;
  895.             break;
  896.         }
  897.     } while (!okCombo());
  898.  
  899.     makeNewImage();
  900. }
  901.  
  902. void changeFormat(void)
  903. {
  904.     do {
  905.         switch(format) {
  906.           case GL_RGB:
  907.             format = GL_RGBA;
  908.             break;
  909.           case GL_RGBA:
  910.             format = GL_DEPTH_COMPONENT;
  911.             break;
  912.           case GL_DEPTH_COMPONENT:
  913.             format = GL_COLOR_INDEX;
  914.             break;
  915.           case GL_COLOR_INDEX:
  916.             format = GL_STENCIL_INDEX;
  917.             break;
  918.           case GL_STENCIL_INDEX:
  919.             format = GL_RED;
  920.             break;
  921.           case GL_RED:
  922.             format = GL_GREEN;
  923.             break;
  924.           case GL_GREEN:
  925.             format = GL_BLUE;
  926.             break;
  927.           case GL_BLUE:
  928.             format = GL_ALPHA;
  929.             break;
  930.           case GL_ALPHA:
  931.             format = GL_LUMINANCE;
  932.             break;
  933.           case GL_LUMINANCE:
  934.             format = GL_LUMINANCE_ALPHA;
  935.             break;
  936.           case GL_LUMINANCE_ALPHA:
  937.             format = GL_RGB;
  938.             break;
  939.         }
  940.     } while (!okCombo());
  941.  
  942.     makeNewImage();
  943. }
  944.  
  945. void changeTest(void)
  946. {
  947.     do {
  948.         switch(test) {
  949.           case TEST_DRAW:
  950.             test = TEST_COPY;
  951.             break;
  952.           case TEST_COPY:
  953.             test = TEST_READ;
  954.             break;
  955.           case TEST_READ:
  956.             test = TEST_DRAW;
  957.             break;
  958.         }
  959.     } while (!okCombo());
  960. }
  961.  
  962.  
  963. static void Usage(void)
  964. {
  965.     fprintf(stderr, "Usage: pixtest [-s] [-geometry WxH+X+Y] <filename>\n");
  966.     exit(1);
  967. }
  968.  
  969. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  970. {
  971.     if ((e->type == MapNotify) && (e->xmap.window == (Window) arg)) {
  972.     return GL_TRUE;
  973.     }
  974.     return GL_FALSE;
  975. }
  976.  
  977. int main(int argc, char** argv)
  978. {
  979.     XVisualInfo *vi;
  980.     Colormap cmap;
  981.     XSetWindowAttributes swa;
  982.     XSizeHints sizehints;
  983.     GLXContext cx;
  984.     XEvent event;
  985.     GLboolean needDisplay;
  986.     XColor white;
  987.     char *geometry = NULL;
  988.     char *filename;
  989.     int i;
  990.  
  991.     zoomx = 1.0;
  992.     zoomy = 1.0;
  993.     format = GL_RGB;
  994.     copyFormat = GL_COLOR;
  995.     type = GL_UNSIGNED_BYTE;
  996.     filename = NULL;
  997.     doubleBuffer = GL_TRUE;
  998.     rgbMode = GL_TRUE;
  999.     for (i = 1; i < argc; i++) {
  1000.     if (!strcmp(argv[i], "-geometry")) {
  1001.         i++;
  1002.         geometry = argv[i];
  1003.         if (geometry == NULL) {
  1004.         Usage();
  1005.         }
  1006.     } else if (argv[i][0] == '-') {
  1007.             switch (argv[i][1]) {
  1008.           case 's':
  1009.         doubleBuffer = GL_FALSE;
  1010.         break;
  1011.           case 'c':
  1012.         rgbMode = GL_FALSE;
  1013.         break;
  1014.               default:
  1015.                 Usage();
  1016.             }
  1017.         } else {
  1018.         if (filename == NULL) {
  1019.         filename=argv[i];
  1020.         } else {
  1021.         Usage();
  1022.         }
  1023.         }
  1024.     }
  1025.     if (filename == NULL) {
  1026.         Usage();
  1027.     }
  1028.  
  1029.     image = ImageLoad(filename);
  1030.     windowWidth = 4 * image->sizeX;
  1031.     windowHeight = 2 * image->sizeY;
  1032.  
  1033.     dpy = XOpenDisplay(0);
  1034.     if (!dpy) {
  1035.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  1036.     return -1;
  1037.     }
  1038.  
  1039.     vi = glXChooseVisual(dpy, DefaultScreen(dpy),
  1040.         doubleBuffer ? (rgbMode ? RGB_DB_attributes : CI_DB_attributes) :
  1041.         (rgbMode ? RGB_SB_attributes : CI_SB_attributes));
  1042.     if (!vi) {
  1043.     fprintf(stderr, "No appropriate visual on \"%s\"\n",
  1044.         getenv("DISPLAY"));
  1045.     return -1;
  1046.     }
  1047.  
  1048.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  1049.                rgbMode ? AllocNone : AllocAll);
  1050.     if (rgbMode) {
  1051.     white.red = ~0;
  1052.     white.green = ~0;
  1053.     white.blue = ~0;
  1054.     XAllocColor(dpy, cmap, &white);
  1055.     swa.background_pixel = white.pixel;
  1056.     } else {
  1057.     swa.background_pixel = 15;
  1058.     }
  1059.  
  1060.     if (!rgbMode) {
  1061.     XColor buf;
  1062.     int i;
  1063.  
  1064.     buf.flags = DoRed | DoGreen | DoBlue;
  1065.  
  1066.     /* Init color map */
  1067.     for (i=0; i<16; i++) {
  1068.         buf.pixel = i;
  1069.         buf.blue = (i & 4) ? 65535 : 0;
  1070.         buf.green = (i & 2) ? 65535 : 0;
  1071.         buf.red = (i & 1) ? 65535 : 0;
  1072.         if (i > 8) {
  1073.         buf.red /= 2;
  1074.         buf.green /= 2;
  1075.         buf.blue /= 2;
  1076.         }
  1077.         XStoreColor(dpy, cmap, &buf);
  1078.     }
  1079.     }
  1080.  
  1081.     sizehints.flags = PPosition | PSize;
  1082.     sizehints.width = windowWidth;
  1083.     sizehints.height = windowHeight;
  1084.     sizehints.x = 10;
  1085.     sizehints.y = 10;
  1086.     if(geometry) {
  1087.     int flags, x, y, width, height;
  1088.  
  1089.     flags = XParseGeometry(geometry, &x, &y,
  1090.                    (unsigned int *)&width,
  1091.                    (unsigned int *)&height);
  1092.         if(WidthValue & flags) {
  1093.         sizehints.flags |= USSize;
  1094.         sizehints.width = width;
  1095.         windowWidth = width;
  1096.     }
  1097.     if(HeightValue & flags) {
  1098.         sizehints.flags |= USSize;
  1099.         sizehints.height = height;
  1100.         windowHeight = height;
  1101.     }
  1102.     if(XValue & flags) {
  1103.         if(XNegative & flags)
  1104.         x = DisplayWidth(dpy, DefaultScreen(dpy)) + x 
  1105.             - sizehints.width;
  1106.             sizehints.flags |= USPosition;
  1107.         sizehints.x = x;
  1108.     }
  1109.     if(YValue & flags) {
  1110.         if(YNegative & flags)
  1111.         y = DisplayHeight(dpy, DefaultScreen(dpy)) + y 
  1112.             - sizehints.height;
  1113.             sizehints.flags |= USPosition;
  1114.         sizehints.y = y;
  1115.     }
  1116.     }
  1117.  
  1118.     swa.border_pixel = 0;
  1119.     swa.background_pixel = white.pixel;
  1120.     swa.colormap = cmap;
  1121.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  1122.     | KeyReleaseMask;
  1123.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 
  1124.                sizehints.x, sizehints.y,
  1125.                sizehints.width, sizehints.height,
  1126.                0, vi->depth, InputOutput, vi->visual,
  1127.                CWBackPixel|CWBorderPixel|CWColormap|CWEventMask,
  1128.                &swa);
  1129.     XSetStandardProperties(dpy, window, "pixtest", "pixtest", None,
  1130.                            argv, argc, &sizehints);
  1131.     XSetWMColormapWindows(dpy, window, &window, 1);
  1132.     XMapWindow(dpy, window);
  1133.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  1134.  
  1135.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  1136.     if (!glXMakeCurrent(dpy, window, cx)) {
  1137.     fprintf(stderr, "Can't make window current to context\n");
  1138.     return -1;
  1139.     }
  1140.  
  1141.     Init();
  1142.  
  1143.     needDisplay = GL_TRUE;
  1144.     for (;;) {
  1145.     do {
  1146.         XNextEvent(dpy, &event);
  1147.         switch (event.type) {
  1148.           case Expose:
  1149.         needDisplay = GL_TRUE;
  1150.         break;
  1151.           case ConfigureNotify:
  1152.         windowWidth = event.xconfigure.width;
  1153.         windowHeight = event.xconfigure.height;
  1154.         glViewport(0, 0, windowWidth, windowHeight);
  1155.         needDisplay = GL_TRUE;
  1156.         break;
  1157.           case KeyPress:
  1158.         {
  1159.             char buf[100];
  1160.             int rv;
  1161.             KeySym ks;
  1162.             GLboolean setNeed = GL_TRUE;
  1163.  
  1164.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  1165.             switch (ks) {
  1166.               case XK_Escape:
  1167.             exit(0);
  1168.               case XK_I:
  1169.               case XK_i:
  1170.             setNeed = GL_FALSE;
  1171.             glXSwapBuffers(dpy, window);
  1172.             break;
  1173.               case XK_x:
  1174.             i = zoomx / 0.125;
  1175.             i++;
  1176.             zoomx = i / 8.0;
  1177.             break;
  1178.               case XK_X:
  1179.             i = zoomx / 0.125;
  1180.             i--;
  1181.             zoomx = i / 8.0;
  1182.             break;
  1183.               case XK_y:
  1184.             i = zoomy / 0.125;
  1185.             i++;
  1186.             zoomy = i / 8.0;
  1187.             break;
  1188.               case XK_Y:
  1189.             i = zoomy / 0.125;
  1190.             i--;
  1191.             zoomy = i / 8.0;
  1192.             break;
  1193.               case XK_Left:
  1194.             centerx -= 9;
  1195.             break;
  1196.               case XK_Right:
  1197.             centerx += 9;
  1198.             break;
  1199.               case XK_Up:
  1200.             centery += 9;
  1201.             break;
  1202.               case XK_Down:
  1203.             centery -= 9;
  1204.             break;
  1205.               case XK_B:
  1206.               case XK_b:
  1207.             biasing = 1-biasing;
  1208.             if (biasing) {
  1209.                 printf("Biasing on\n");
  1210.             } else {
  1211.                 printf("Biasing off\n");
  1212.             }
  1213.             break;
  1214.               case XK_M:
  1215.               case XK_m:
  1216.             mapping = 1-mapping;
  1217.             if (mapping) {
  1218.                 printf("Mapping on\n");
  1219.             } else {
  1220.                 printf("Mapping off\n");
  1221.             }
  1222.             break;
  1223.               case XK_S:
  1224.               case XK_s:
  1225.             scissor = 1-scissor;
  1226.             if (scissor) {
  1227.                 printf("Scissoring on\n");
  1228.             } else {
  1229.                 printf("Scissoring off\n");
  1230.             }
  1231.             break;
  1232.               case XK_R:
  1233.               case XK_r:
  1234.             changeTest();
  1235.             break;
  1236.               case XK_T:
  1237.               case XK_t:
  1238.             changeType();
  1239.             break;
  1240.               case XK_F:
  1241.               case XK_f:
  1242.             changeFormat();
  1243.             break;
  1244.               case XK_A:
  1245.               case XK_a:
  1246.             alphatst = 1-alphatst;
  1247.             if (alphatst) {
  1248.                 printf("Alpha test on\n");
  1249.             } else {
  1250.                 printf("Alpha test off\n");
  1251.             }
  1252.             break;
  1253.               case XK_E:
  1254.               case XK_e:
  1255.             swapBytes = 1-swapBytes;
  1256.             if (swapBytes) {
  1257.                 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE);
  1258.                 glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
  1259.                 glPixelStorei(GL_PACK_SWAP_BYTES, GL_TRUE);
  1260.                 glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
  1261.             } else {
  1262.                 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  1263.                 glPixelStorei(GL_UNPACK_LSB_FIRST, GL_TRUE);
  1264.                 glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
  1265.                 glPixelStorei(GL_PACK_LSB_FIRST, GL_TRUE);
  1266.             }
  1267.             makeNewImage();
  1268.             break;
  1269.               case XK_W:
  1270.               case XK_w:
  1271.             alignShift = (alignShift+1)&3;
  1272.             makeNewImage();
  1273.             break;
  1274.               case XK_D:
  1275.               case XK_d:
  1276.             dlisted = 1-dlisted;
  1277.             if (dlisted) {
  1278.                 printf("Display listing\n");
  1279.             } else {
  1280.                 printf("Immediate mode\n");
  1281.             }
  1282.             break;
  1283.               default:
  1284.             setNeed = GL_FALSE;
  1285.             break;
  1286.             }
  1287.             if (setNeed) needDisplay = GL_TRUE;
  1288.         }
  1289.         break;
  1290.         }
  1291.     } while (XPending(dpy) != 0);
  1292.  
  1293.     if (needDisplay) {
  1294.         needDisplay = GL_FALSE;
  1295.         Redraw();
  1296.     }
  1297.     }
  1298. }
  1299.